#ifndef _SPI_FLASH_CMD_H_
#define	_SPI_FLASH_CMD_H_

#include "stdint.h"
#include "osObjects.h"

// command list
#define SPI_FLASH_CMD_Write_Enable                              0x06
#define SPI_FLASH_CMD_Write_Disable                             0x04
#define SPI_FLASH_CMD_SRWrite_Enable                            0x50
#define SPI_FLASH_CMD_Read_StReg1                               0x05
#define SPI_FLASH_CMD_Read_StReg2                               0x35
#define SPI_FLASH_CMD_Read_StReg3                               0x15
#define SPI_FLASH_CMD_Write_StReg1                              0x01
#define SPI_FLASH_CMD_Write_StReg2                              0x31
#define SPI_FLASH_CMD_Write_StReg3                              0x11
#define SPI_FLASH_CMD_Read_Data                                 0x03
#define SPI_FLASH_CMD_Fast_Read                                 0x0B
#define SPI_FLASH_CMD_Dual_Output                               0x3B
#define SPI_FLASH_CMD_Dual_IO                                   0xBB
#define SPI_FLASH_CMD_Quad_Output                               0x6B
#define SPI_FLASH_CMD_Quad_IO                                   0xEB
#define SPI_FLASH_CMD_Quad_IO_Word                              0xE7
#define SPI_FLASH_CMD_Page_Program                              0x02
#define SPI_FLASH_CMD_Quad_Page_Program                         0x32
#define SPI_FLASH_CMD_Sector_Erase                              0x20
#define SPI_FLASH_CMD_Block_Erase_32K                           0x52
#define SPI_FLASH_CMD_Block_Erase_64K                           0xD8
#define SPI_FLASH_CMD_Chip_Erase                                0x60
#define SPI_FLASH_CMD_Enable_QPI                                0x38
#define SPI_FLASH_CMD_Enable_Reset                              0x66
#define SPI_FLASH_CMD_Reset                                     0x99
#define SPI_FLASH_CMD_Set_Burst_with_Wrap                       0x77
#define SPI_FLASH_CMD_Erase SecurityReg                         0x44
#define SPI_FLASH_CMD_Program SecurityReg                       0x42
#define SPI_FLASH_CMD_Read SecurityReg                          0x48
#define SPI_FLASH_CMD_Individual_Block_Lock                     0x36
#define SPI_FLASH_CMD_Individual_Block_Unlock                   0x39
#define SPI_FLASH_CMD_Read_Block_Lock                           0x3D
#define SPI_FLASH_CMD_Global_Block_Lock                         0x7E
#define SPI_FLASH_CMD_Global_Block_Unlock                       0x98

// mode
typedef enum
{
    SPI_FLASH_IDLE             =                           0x00,
    SPI_FLASH_READ             =                           0x01,
    SPI_FLASH_WRITE            =                           0x02,
} flash_spi_rw_st_type;

typedef struct
{
    osMutexId mid_flash;
    flash_spi_rw_st_type rw_st;
} flash_spi_info_type;

typedef const struct
{
    uint32_t SPI_FLASH_PAGE_SIZE;
    uint32_t SPI_FLASH_PAGE_MASK;
    uint32_t SPI_FLASH_SECTOR_SIZE;
    uint32_t SPI_FLASH_SECTOR_MASK;
    uint32_t SPI_FLASH_BLOCK_SIZE;
    uint32_t SPI_FLASH_BLOCK_MASK;
    uint32_t SPI_FLASH_CHIP_SIZE;
    uint32_t SPI_FLASH_CHIP_MASK; 
    
    void (*cs)(uint8_t st);
    uint8_t (*rw)(uint8_t data);
    uint8_t (*read)(uint8_t *datar, uint32_t Len);
    uint8_t (*write)(uint8_t *dataw, uint32_t Len);
    uint8_t (*dma_read)(uint8_t *Data, uint32_t Len);
    uint8_t (*dma_write)(uint8_t *Data, uint32_t Len);
    
    flash_spi_info_type *info;
} flash_spi_cfg_type;

// statue define
#define SPI_FLASH_ST_BUSY_MASK                                0x01
#define SPI_FLASH_ST_WRITE_EN                                 0x02

//function
uint32_t spi_flash_st_read(flash_spi_cfg_type *spi);
uint8_t  spi_flash_busy(flash_spi_cfg_type *spi);


void spi_flash_write_enable(flash_spi_cfg_type *spi);
void spi_flash_write_disable(flash_spi_cfg_type *spi);
uint8_t spi_flash_sector_erase(flash_spi_cfg_type *spi, uint32_t addr);
uint8_t spi_flash_block_erase(flash_spi_cfg_type *spi, uint32_t addr);
uint8_t spi_flash_chip_erase(flash_spi_cfg_type *spi );

uint8_t spi_flash_read(flash_spi_cfg_type *spi, uint32_t addr,uint32_t Len,uint8_t *Des);
uint8_t spi_flash_write(flash_spi_cfg_type *spi, uint32_t addr,uint32_t Len,uint8_t *Src);
uint8_t spi_flash_dma_read(flash_spi_cfg_type *spi, uint32_t addr,uint32_t Len,uint8_t *Des);
uint8_t spi_flash_dma_write(flash_spi_cfg_type *spi, uint32_t addr,uint32_t Len,uint8_t *Src);

#endif	/* _SPI_FLASH_CMD_H_ */

